package com.myboot.demo;

import com.alibaba.druid.pool.DruidDataSource;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

@SpringBootApplication
public class DemoApplication {
    private static DruidDataSource druidDataSource;
    private static ZkClient zkClient;
    private static ObjectMapper mapper = new ObjectMapper();

    public static void main(String[] args) throws Exception {
        SpringApplication.run(DemoApplication.class, args);
        //初始化
        initZookeeper();
        //第一次执行
        configDruidSource();
    }

    /**
     *  注册zookeeper
     */
    private static void initZookeeper() {
        zkClient = new ZkClient("mylinux01:2181,myllinux03:2181");
        zkClient.setZkSerializer(new ZkStrSerializer());

        //注册监听器
        zkClient.subscribeDataChanges("/jdbc", new IZkDataListener() {
            public void handleDataChange(String path, Object data) throws Exception {
                System.out.println(path + "连接池改变 , 新连接 " + data);
                druidDataSource.close();
                configDruidSource();
            }
            public void handleDataDeleted(String path) {
                System.out.println(path + " 被删除!");
                druidDataSource.close();
            }
        });
    }

    /**
     * 获取更新sql连接字符串,更新,执行sql
     * @throws Exception
     */
    private static void configDruidSource() throws Exception {
        //获取更新sql连接字符串
        JDBCConfig myConfig = getJDBCConfig();
        //更新
        updateDruidDuConfig(myConfig);
        try {
            //执行sql
            executeSQL();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 测试执行sql
     * @throws SQLException
     */
    private static void executeSQL() throws SQLException {
        Connection connection = druidDataSource.getConnection();
        PreparedStatement pst = connection.prepareStatement( "SELECT id,username FROM student;" );
        ResultSet rs = pst.executeQuery();
        while (rs.next()) {
            System.out.println("id : " + rs.getString(1) + " , username : " + rs.getString(2));
        }
    }

    /**
     * 更新sql连接配置
     * @param myConfig
     * @throws Exception
     */
    private static void updateDruidDuConfig(JDBCConfig myConfig) throws Exception {
        Properties pro=new Properties();
        pro.setProperty("druid.driverClassName",myConfig.getDriver());
        pro.setProperty("druid.url",myConfig.getUrl());
        pro.setProperty("druid.username",myConfig.getUsername());
        pro.setProperty("druid.password",myConfig.getPassword());
        druidDataSource= new DruidDataSource();
        druidDataSource.configFromPropety(pro);
    }

    /**
     * 获取更新sql连接字符串
     * @return
     */
    private static JDBCConfig getJDBCConfig() {
        Object data = zkClient.readData("/jdbc");
        try {
            JDBCConfig myConfig = mapper.readValue(data.toString(), JDBCConfig.class);
            System.out.println(myConfig.toString());
            return myConfig;
        } catch (JsonProcessingException e) {
            return new JDBCConfig();
        }
    }
}
